import igraph
import numpy as np
import networkx
import matplotlib.pyplot as plt


def network_igraph():
    """
    igraph画网络图（有向/无向图）
    :return:
    """
    vertices = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']
    edges = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7),
             (7, 1), (1, 8), (8, 2), (2, 4), (4, 9), (9, 5), (5, 7), (7, 0)]
    graph_style = {'vertex_size': 20}
    g = igraph.Graph(vertex_attrs={'label': vertices}, edges=edges, directed=True)
    g.write_svg('./data/simple_start.svg', width=500, height=300, **graph_style)


class NetworkNetworkx(object):
    def __init__(self):
        self.g = networkx.Graph()

    @staticmethod
    def basic():
        """

        :return:
        """
        g = networkx.DiGraph()

        g.add_edges_from([('K', 'I'), ('R', 'T'), ('V', 'T')], weight=3)
        g.add_edges_from([('T', 'K'), ('T', 'H'), ('I', 'T'), ('T', 'H')], weight=4)
        g.add_edges_from([('I', 'R'), ('H', 'N')], weight=5)
        g.add_edges_from([('R', 'N')], weight=6)

        edge_label = dict([(((u, v,), d['weight'])) for u, v, d in g.edges(data=True)])

        red_edges = [('R', 'T'), ('T', 'K')]
        edge_colors = ['green' if not edge in red_edges else 'red' for edge in g.edges()]

        pos = networkx.spring_layout(g)

        networkx.draw_networkx_edges(g, pos, width=2.0, alpha=0.65)
        networkx.draw_networkx_edge_labels(g, pos, edge_labels=edge_label)

        networkx.draw(g, pos, node_size=300, edge_color=edge_colors)

        plt.show()

    def biycle(self):
        """

        :return:
        """
        def gen_router_edges(r):
            return [(r[n], r[n + 1]) for n in range(len(r) - 1)]

        graph_routes = [[11, 3, 4, 1, 2], [5, 6, 3, 0, 1], [2, 0, 1, 3, 11, 5]]
        edges = []
        for r in graph_routes:
            route_edges = gen_router_edges(r)
            self.g.add_nodes_from(r)
            self.g.add_edges_from(route_edges)
            edges.append(route_edges)

        print('图有{}个节点和{}个边'.format(self.g.number_of_nodes(), self.g.number_of_edges()))

        pos = networkx.spring_layout(self.g)
        networkx.draw_networkx_nodes(self.g, pos)
        networkx.draw_networkx_edges(self.g, pos)

        colors = ['g', 'b', 'y']
        linewidths = [22, 14, 10]

        for ctr, edgelist, in enumerate(edges):
            networkx.draw_networkx_edges(self.g, pos, edgelist, edge_color=colors[ctr],
                                         width=linewidths[ctr])

        plt.show()

    def shortest_path(self):
        self.g.add_edge('m', 'i', weight=0.1)
        self.g.add_edge('i', 'a', weight=1.5)
        self.g.add_edge('m', 'a', weight=1.0)
        self.g.add_edge('a', 'e', weight=0.75)
        self.g.add_edge('e', 'h', weight=1.5)
        self.g.add_edge('a', 'h', weight=2.2)

        pos = networkx.spring_layout(self.g)

        print(networkx.shortest_path(self.g, 'i', 'h'))
        networkx.draw(self.g, pos, with_labels=True)

        plt.show()

    @staticmethod
    def max_flow_value():
        """
        最大流量问题
        :return:
        """
        g = networkx.DiGraph()
        g.add_edge('p', 'y', capacity=5.0)
        g.add_edge('p', 's', capacity=4.0)
        g.add_edge('y', 't', capacity=3.0)
        g.add_edge('s', 'h', capacity=5.0)
        g.add_edge('s', 'o', capacity=4.0)

        flow_value = networkx.max_flow_min_cost(g, 'p', 'o')
        print(flow_value)

        pos = networkx.spring_layout(g)
        networkx.draw(g, pos, node_color='r', with_labels=True)

        plt.show()

    def les_miserables(self):
        """
        悲惨世界人物关系
        :return:
        """
        g = networkx.read_gml('./data/lesmiserables.gml')
        g_plot = g.copy()

        pos = networkx.spring_layout(g_plot)
        networkx.draw(g, pos, node_size=5, edge_color='b', alpha=0.45, font_size=9, with_labels=True)

        plt.show()

# igraph
# network_igraph()

# networkx
nx = NetworkNetworkx()
# nx.basic()
# nx.biycle()
# nx.shortest_path()
nx.max_flow_value()
# nx.les_miserables()
